package cn.wellcare.shiro;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import cn.wellcare.bo.SystemUsersBO;
import cn.wellcare.constant.Constants;
import cn.wellcare.entity.SystemResources;
import cn.wellcare.entity.SystemUserRole;
import cn.wellcare.pojo.ServiceResponse;
import cn.wellcare.service.SystemResourcesService;
import cn.wellcare.service.SystemUserRoleService;
import cn.wellcare.service.SystemUsersService;
import cn.wellcare.utils.CommonUtils;

/**
 * shiro权限realm
 * 
 * @author zhaihl
 *
 */
public class ShiroDbRealm extends AuthorizingRealm {

	Logger log = Logger.getLogger(this.getClass());

	@Resource
	private SystemUsersService SystemUsersService;

	@Resource
	private SystemUserRoleService systemUserRoleService;
	@Resource
	private SystemResourcesService resourceService;

	/**
	 * Shiro登录认证(原理：机构提交 机构名和密码 --- shiro 封装令牌 ---- realm 通过机构名将密码查询返回 ---- shiro
	 * 自动去比较查询出密码和机构输入密码是否一致---- 进行登陆控制 )
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
			throws AuthenticationException {
		log.info("Shiro开始登录认证");
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;

		// ServiceResult<List<SysOrganization>> adminResult =
		// organizationService.getByAuthName(token.getUsername());
		ServiceResponse<SystemUsersBO> userResult = SystemUsersService.getByLoginName(token.getUsername());
		if (!userResult.getSuccess()) {
			log.error(userResult.getMsgInfo());
			return null;
		}
		SystemUsersBO user = userResult.getData();
		// 账号不存在
		if (user == null) {
			log.error("用户不存在，用户名：" + token.getUsername());
			throw new UnknownAccountException();
		}
		// 账号未启用
		if (user.getDeleted() == 1) {
			log.error("账号是非正常状态：" + token.getUsername());
			throw new DisabledAccountException();
		}
		// 认证缓存信息
		return new SimpleAuthenticationInfo(user, user.getPwd().toCharArray(), getName());

	}

	/**
	 * Shiro权限认证
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

		System.out.println("权限验证。。。。。。。。。。。");
		SystemUsersBO users = (SystemUsersBO) principals.getPrimaryPrincipal();
		SystemUserRole userRole = systemUserRoleService.getSystemUserRoleByUserId(users.getId());

		ServiceResponse<List<SystemResources>> resourcesResult = resourceService
				.getResourceByRoleId(userRole.getRoleId());

		if (!resourcesResult.getSuccess()) {
			log.error(resourcesResult.getMsgInfo());
		}

		List<SystemResources> resourceList = resourcesResult.getData();
		if (resourceList == null || resourceList.size() == 0) {
			log.error("该机构所属角色没有任何权限");
		}

		Set<String> urlSet = new HashSet<String>();
		if (resourceList != null && resourceList.size() > 0) {
			for (SystemResources resource : resourceList) {
				String url = resource.getUrl();
				if (!CommonUtils.isNull(url)) {
					// 用逗号分隔资源表的url字段，该字段可存储多个url，并用英文逗号（，）分隔
					String[] split = url.split(",");
					for (String urlSplit : split) {
						// 如果url中带参数，则截去参数部分
						int indexOf = urlSplit.indexOf("?");
						if (indexOf != -1) {
							urlSplit = urlSplit.substring(0, indexOf);
						}
						urlSet.add(urlSplit);
					}
				}
			}
		}

		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		info.addStringPermissions(urlSet);
		log.info("---------------------doGetAuthorizationInfo end" + urlSet);

		return info;
	}

	/**
	 * 管理员不验证
	 */
	@Override
	public boolean isPermitted(PrincipalCollection principals, String permission) {
		SystemUsersBO user = (SystemUsersBO) principals.getPrimaryPrincipal();
		return Constants.SYSTEM_ADMIN_CODE.toUpperCase().equals(user.getRoleCode())
				|| super.isPermitted(principals, permission);
	}

	@Override
	public boolean hasRole(PrincipalCollection principals, String roleIdentifier) {
		SystemUsersBO user = (SystemUsersBO) principals.getPrimaryPrincipal();
		return Constants.SYSTEM_ADMIN_CODE.toUpperCase().equals(user.getRoleCode())
				|| super.hasRole(principals, roleIdentifier);
	}

}
